package com.ihai.spring.boot.sample.distributed.counter.handler;

import com.ihai.spring.boot.sample.distributed.counter.manager.CounterManagerMBean;
import com.ihai.spring.boot.sample.distributed.counter.model.ICounter;
import com.ihai.spring.boot.sample.distributed.counter.remote.Node;
import com.ihai.spring.boot.sample.distributed.counter.remote.NodeManager;
import com.ihai.spring.boot.sample.distributed.counter.util.JmxRemoteUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.*;

/**
 * DESC
 *
 * @author 张驰
 * @date 2019/12/26
 */
public class NoticeHandler {
    private static final Logger logger = LoggerFactory.getLogger(NoticeHandler.class);
    private static final ConcurrentMap<String, ICounter> counterConcurrentMap = new ConcurrentHashMap<>();

    private static ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();

    static {
        executor.scheduleWithFixedDelay(new Runnable() {
            @Override
            public void run() {
                if (!counterConcurrentMap.isEmpty()) {
                    Iterator<ConcurrentMap.Entry<String, ICounter>> iterator = counterConcurrentMap.entrySet().iterator();
                    while (iterator != null && iterator.hasNext()) {
                        ConcurrentMap.Entry<String, ICounter> entry = iterator.next();
                        if (NodeManager.isMaster()) {
                            for (Node node : NodeManager.getClusters()) {
                                if (!node.equals(NodeManager.getMaster())) {
                                    try {
                                        CounterManagerMBean counterManager = JmxRemoteUtil.getMBean(node, "iHaiCounter", "iHaiCounter:name=counterManager", CounterManagerMBean.class);
                                        counterManager.asynFromRemote(entry.getKey(), entry.getValue());
                                    } catch (Exception e) {
                                        logger.debug("notice failed.", e);
                                    }
                                }
                            }
                        }
                    }
                    counterConcurrentMap.clear();
                }
            }
        }, 0, 500, TimeUnit.MILLISECONDS);
    }

    public static void addNoticeElement(ICounter counter) {
        counterConcurrentMap.put(counter.getName(), counter);
    }

    public static void removeCounter(String name) {
        counterConcurrentMap.put(name, null);
    }
}
